library(beeswarm)
library(naniar)
library(zoo)

Attaching package: ‘zoo’

The following objects are masked from ‘package:base’:

    as.Date, as.Date.numeric
# install.packages("zoo")
library(janitor)
library(dplyr)
# install.packages("GGally")
# library(sets)
library(tidyverse)
library(ggplot2)
library(GGally) # for ggpairs
# install.packages("maps")
# library(maps)
load_file <- function(file_path){
  read_csv(file_path)
}

tx_data <- load_file("./../data/COVID-19_cases_TX.csv")

── Column specification ───────────────────────────────────────────────────────────────────────────────────────────
cols(
  county_fips_code = col_character(),
  county_name = col_character(),
  state = col_character(),
  state_fips_code = col_double(),
  date = col_date(format = ""),
  confirmed_cases = col_double(),
  deaths = col_double()
)
global_mobility_report <- load_file("./../data/Global_Mobility_Report.csv")

── Column specification ───────────────────────────────────────────────────────────────────────────────────────────
cols(
  country_region_code = col_character(),
  country_region = col_character(),
  sub_region_1 = col_character(),
  sub_region_2 = col_logical(),
  metro_area = col_logical(),
  iso_3166_2_code = col_character(),
  census_fips_code = col_logical(),
  date = col_date(format = ""),
  retail_and_recreation_percent_change_from_baseline = col_double(),
  grocery_and_pharmacy_percent_change_from_baseline = col_double(),
  parks_percent_change_from_baseline = col_double(),
  transit_stations_percent_change_from_baseline = col_double(),
  workplaces_percent_change_from_baseline = col_double(),
  residential_percent_change_from_baseline = col_double()
)

4199216 parsing failures.
 row        col           expected                  actual                                   file
3036 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
3037 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
3038 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
3039 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
3040 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
.... .......... .................. ....................... ......................................
See problems(...) for more details.
cases_plus_census <- load_file("./../data/COVID-19_cases_plus_census.csv")

── Column specification ───────────────────────────────────────────────────────────────────────────────────────────
cols(
  .default = col_double(),
  county_fips_code = col_character(),
  county_name = col_character(),
  state = col_character(),
  state_fips_code = col_character(),
  date = col_date(format = ""),
  geo_id = col_character(),
  pop_5_years_over = col_logical(),
  speak_only_english_at_home = col_logical(),
  speak_spanish_at_home = col_logical(),
  speak_spanish_at_home_low_english = col_logical(),
  pop_15_and_over = col_logical(),
  pop_never_married = col_logical(),
  pop_now_married = col_logical(),
  pop_separated = col_logical(),
  pop_widowed = col_logical(),
  pop_divorced = col_logical()
)
ℹ Use `spec()` for the full column specifications.
cols_keep <- c("county_fips_code", "confirmed_cases", "deaths", "median_income", "male_pop", "female_pop", "total_pop", "median_age", "worked_at_home")
subset_census <- cases_plus_census[cols_keep]

cols_keep <- c("date", "retail_and_recreation_percent_change_from_baseline", "grocery_and_pharmacy_percent_change_from_baseline", "parks_percent_change_from_baseline", "transit_stations_percent_change_from_baseline", "workplaces_percent_change_from_baseline", "residential_percent_change_from_baseline")
subset_mobility <- global_mobility_report[cols_keep]
subset_mobility$date <- as.Date(subset_mobility$date, format="%Y-%m-%d")
# global_mobility_report
vis_miss(global_mobility_report, sort_miss = T, warn_large_data= F)

vis_miss(tx_data, sort_miss = T, warn_large_data= F)

vis_miss(subset_census, sort_miss = T, warn_large_data = F)

library(RColorBrewer)
plot_vs_county <- function(df, col_val, percentile=FALSE,
                           fips_title="county_fips_code", banks=6, 
                           legend_title="", graphic_title=""){
  # Subset for speed 
  df <- df[c(fips_title, col_val)]
  
  # Get county data
  gcounty <- ggplot2::map_data("county")
  # USA map data
  gusa <- map_data("state")
  
  if (banks > 9){
    mycolors <- colorRampPalette(brewer.pal(9, "Reds"))(banks)
  }
  
  # Format with subregions
  fipstab <-
      transmute(maps::county.fips, fips, county = sub(":.*", "", polyname)) %>%
      unique() %>%
      separate(county, c("region", "subregion"), sep = ",")
  
  # Combine in desired order (NA for missing)
  gcounty <- left_join(gcounty, fipstab, c("region", "subregion"))


  dis <- df
  dis$rprop <- rank(df[col_val])
  dis$pcls <- cut(100 * percent_rank(df[col_val]), seq(0, 100, len = banks),
                        include.lowest = TRUE)

  # Missing data
  anti_join(gcounty, dis, by = c("fips" = fips_title)) %>%
    select(region, subregion) %>%
    unique()
  gcounty_pop <- left_join(gcounty, dis, by = c("fips" = fips_title))
  fill_vals <- gcounty_pop[col_val]

  # Plot
  if (legend_title == ""){
    legend_title <- col_val
  }

  if (percentile == FALSE){
    # names(gcounty_pop)[names(gcounty_pop) == col_val] <- "col_of_interest"
    plt <- ggplot(gcounty_pop) +
      geom_polygon(aes(long, lat, group = group, fill = get(col_val)),
                   color = "grey", size = 0.1, name="Percent Infected") +
      geom_polygon(aes(long, lat, group = group),
                   fill = NA, data = gusa, color = "lightgrey") +
      coord_map("bonne", parameters = 41.6) + ggthemes::theme_map()+
      scale_fill_gradient2()
       # scale_fill_gradient(low = "white", high = "red", na.value = "grey")
      # scale_fill_gradientn(colours = terrain.colors(10))
  }

  if (percentile == TRUE){
    plt <- ggplot(gcounty_pop) +
      geom_polygon(aes(long, lat, group = group, fill = pcls),
                   color = "grey", size = 0.1) +
      geom_polygon(aes(long, lat, group = group),
                   fill = NA, data = gusa, color = "lightgrey") +
      coord_map("bonne", parameters = 41.6) + ggthemes::theme_map() +
      scale_fill_manual(values = mycolors, na.value = "grey") +
      # scale_fill_brewer(palette = "viridis", na.value = "grey") +
      theme(plot.title = element_text(family = "Helvetica", face = "bold", size = (15)),
            legend.background = element_rect(fill = NA), 
            legend.position = "left")
  }
  plt <- plt + labs(fill=legend_title) + ggtitle(graphic_title)
  plt
}
subset_census
subset_census['pct_infected'] <- subset_census['confirmed_cases']/subset_census['total_pop']
subset_census['pct_deaths'] <- subset_census['deaths']/subset_census['total_pop']
subset_census$county_fips_code <-as.integer(subset_census$county_fips_code)
subset_census
plot_vs_county(subset_census, "pct_infected", legend_title = "Percent Infected")
Ignoring unknown parameters: name

plot_vs_county(subset_census, "pct_infected", percentile = TRUE, banks=11, 
               legend_title = "Percentile Infected",
               graphic_title = "Percentile of Percentage of People Infected by County")

plot_vs_county(subset_census, "pct_deaths", percentile = TRUE, banks=11, 
               legend_title = "Percentile Deaths",
               graphic_title = "Percentile of Percentage of Deaths by County")

census_corr_cols <- c("deaths", "confirmed_cases", "median_income", "male_pop",
                      "female_pop", "total_pop", "median_age", "worked_at_home")
ggcorr(subset_census[census_corr_cols], low="red", mid="grey", high="blue", hjust= .75, size=3, 
       label = TRUE, label_size = 3, label_color = "white") + ggplot2::labs(title = "Pearson Correlation of Important Variables")

country_date_pct_change <- global_mobility_report %>% select(country_region_code
                                                             | contains("date") 
                                                             | contains("percent"))
country_date_pct_change
# country_date_pct_change$retail_and_recreation_percent_change_from_baseline
test <- country_date_pct_change %>% filter(country_region_code == "AE") %>% select(date | retail_and_recreation_percent_change_from_baseline)
ggplot( data = test, aes( date, retail_and_recreation_percent_change_from_baseline )) + 
  # geom_line(aes(y=rollmean(retail_and_recreation_percent_change_from_baseline, k=2, na.pad=TRUE)))
  geom_line()

length(unique(country_date_pct_change$country_region_code))
[1] 135
# uniqueN(country_date_pct_change, by = c("country_region_code"))
xm <- zoo(matrix(1:12, 4, 3), x.Date[1:4])
Error in MATCH(order.by, order.by) : object 'x.Date' not found
LS0tCnRpdGxlOiAiQ2xlYW5lZCBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkoYmVlc3dhcm0pCmxpYnJhcnkobmFuaWFyKQpsaWJyYXJ5KHpvbykKIyBpbnN0YWxsLnBhY2thZ2VzKCJ6b28iKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoZHBseXIpCiMgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikKIyBsaWJyYXJ5KHNldHMpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoR0dhbGx5KSAjIGZvciBnZ3BhaXJzCiMgaW5zdGFsbC5wYWNrYWdlcygibWFwcyIpCiMgbGlicmFyeShtYXBzKQpgYGAKCmBgYHtyfQpsb2FkX2ZpbGUgPC0gZnVuY3Rpb24oZmlsZV9wYXRoKXsKICByZWFkX2NzdihmaWxlX3BhdGgpCn0KCnR4X2RhdGEgPC0gbG9hZF9maWxlKCIuLy4uL2RhdGEvQ09WSUQtMTlfY2FzZXNfVFguY3N2IikKZ2xvYmFsX21vYmlsaXR5X3JlcG9ydCA8LSBsb2FkX2ZpbGUoIi4vLi4vZGF0YS9HbG9iYWxfTW9iaWxpdHlfUmVwb3J0LmNzdiIpCmNhc2VzX3BsdXNfY2Vuc3VzIDwtIGxvYWRfZmlsZSgiLi8uLi9kYXRhL0NPVklELTE5X2Nhc2VzX3BsdXNfY2Vuc3VzLmNzdiIpCmBgYApgYGB7cn0KY29sc19rZWVwIDwtIGMoImNvdW50eV9maXBzX2NvZGUiLCAiY29uZmlybWVkX2Nhc2VzIiwgImRlYXRocyIsICJtZWRpYW5faW5jb21lIiwgIm1hbGVfcG9wIiwgImZlbWFsZV9wb3AiLCAidG90YWxfcG9wIiwgIm1lZGlhbl9hZ2UiLCAid29ya2VkX2F0X2hvbWUiKQpzdWJzZXRfY2Vuc3VzIDwtIGNhc2VzX3BsdXNfY2Vuc3VzW2NvbHNfa2VlcF0KCiMgY29sc19rZWVwIDwtIGMoImRhdGUiLCAicmV0YWlsX2FuZF9yZWNyZWF0aW9uX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUiLCAiZ3JvY2VyeV9hbmRfcGhhcm1hY3lfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSIsICJwYXJrc19wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lIiwgInRyYW5zaXRfc3RhdGlvbnNfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSIsICJ3b3JrcGxhY2VzX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUiLCAicmVzaWRlbnRpYWxfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSIpCiMgc3Vic2V0X21vYmlsaXR5IDwtIGdsb2JhbF9tb2JpbGl0eV9yZXBvcnRbY29sc19rZWVwXQojIGdsbwojIHN1YnNldF9tb2JpbGl0eSRkYXRlIDwtIGFzLkRhdGUoc3Vic2V0X21vYmlsaXR5JGRhdGUsIGZvcm1hdD0iJVktJW0tJWQiKQpgYGAKCmBgYHtyfQojIGdsb2JhbF9tb2JpbGl0eV9yZXBvcnQKdmlzX21pc3MoZ2xvYmFsX21vYmlsaXR5X3JlcG9ydCwgc29ydF9taXNzID0gVCwgd2Fybl9sYXJnZV9kYXRhPSBGKQpgYGAKCgpgYGB7cn0KdmlzX21pc3ModHhfZGF0YSwgc29ydF9taXNzID0gVCwgd2Fybl9sYXJnZV9kYXRhPSBGKQp2aXNfbWlzcyhzdWJzZXRfY2Vuc3VzLCBzb3J0X21pc3MgPSBULCB3YXJuX2xhcmdlX2RhdGEgPSBGKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKcGxvdF92c19jb3VudHkgPC0gZnVuY3Rpb24oZGYsIGNvbF92YWwsIHBlcmNlbnRpbGU9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcHNfdGl0bGU9ImNvdW50eV9maXBzX2NvZGUiLCBiYW5rcz02LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kX3RpdGxlPSIiLCBncmFwaGljX3RpdGxlPSIiKXsKICAjIFN1YnNldCBmb3Igc3BlZWQgCiAgZGYgPC0gZGZbYyhmaXBzX3RpdGxlLCBjb2xfdmFsKV0KICAKICAjIEdldCBjb3VudHkgZGF0YQogIGdjb3VudHkgPC0gZ2dwbG90Mjo6bWFwX2RhdGEoImNvdW50eSIpCiAgIyBVU0EgbWFwIGRhdGEKICBndXNhIDwtIG1hcF9kYXRhKCJzdGF0ZSIpCiAgCiAgaWYgKGJhbmtzID4gOSl7CiAgICBteWNvbG9ycyA8LSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwoOSwgIlJlZHMiKSkoYmFua3MpCiAgfQogIAogICMgRm9ybWF0IHdpdGggc3VicmVnaW9ucwogIGZpcHN0YWIgPC0KICAgICAgdHJhbnNtdXRlKG1hcHM6OmNvdW50eS5maXBzLCBmaXBzLCBjb3VudHkgPSBzdWIoIjouKiIsICIiLCBwb2x5bmFtZSkpICU+JQogICAgICB1bmlxdWUoKSAlPiUKICAgICAgc2VwYXJhdGUoY291bnR5LCBjKCJyZWdpb24iLCAic3VicmVnaW9uIiksIHNlcCA9ICIsIikKICAKICAjIENvbWJpbmUgaW4gZGVzaXJlZCBvcmRlciAoTkEgZm9yIG1pc3NpbmcpCiAgZ2NvdW50eSA8LSBsZWZ0X2pvaW4oZ2NvdW50eSwgZmlwc3RhYiwgYygicmVnaW9uIiwgInN1YnJlZ2lvbiIpKQoKCiAgZGlzIDwtIGRmCiAgZGlzJHJwcm9wIDwtIHJhbmsoZGZbY29sX3ZhbF0pCiAgZGlzJHBjbHMgPC0gY3V0KDEwMCAqIHBlcmNlbnRfcmFuayhkZltjb2xfdmFsXSksIHNlcSgwLCAxMDAsIGxlbiA9IGJhbmtzKSwKICAgICAgICAgICAgICAgICAgICAgICAgaW5jbHVkZS5sb3dlc3QgPSBUUlVFKQoKICAjIE1pc3NpbmcgZGF0YQogIGFudGlfam9pbihnY291bnR5LCBkaXMsIGJ5ID0gYygiZmlwcyIgPSBmaXBzX3RpdGxlKSkgJT4lCiAgICBzZWxlY3QocmVnaW9uLCBzdWJyZWdpb24pICU+JQogICAgdW5pcXVlKCkKICBnY291bnR5X3BvcCA8LSBsZWZ0X2pvaW4oZ2NvdW50eSwgZGlzLCBieSA9IGMoImZpcHMiID0gZmlwc190aXRsZSkpCiAgZmlsbF92YWxzIDwtIGdjb3VudHlfcG9wW2NvbF92YWxdCgogICMgUGxvdAogIGlmIChsZWdlbmRfdGl0bGUgPT0gIiIpewogICAgbGVnZW5kX3RpdGxlIDwtIGNvbF92YWwKICB9CgogIGlmIChwZXJjZW50aWxlID09IEZBTFNFKXsKICAgICMgbmFtZXMoZ2NvdW50eV9wb3ApW25hbWVzKGdjb3VudHlfcG9wKSA9PSBjb2xfdmFsXSA8LSAiY29sX29mX2ludGVyZXN0IgogICAgcGx0IDwtIGdncGxvdChnY291bnR5X3BvcCkgKwogICAgICBnZW9tX3BvbHlnb24oYWVzKGxvbmcsIGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IGdldChjb2xfdmFsKSksCiAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJncmV5Iiwgc2l6ZSA9IDAuMSwgbmFtZT0iUGVyY2VudCBJbmZlY3RlZCIpICsKICAgICAgZ2VvbV9wb2x5Z29uKGFlcyhsb25nLCBsYXQsIGdyb3VwID0gZ3JvdXApLAogICAgICAgICAgICAgICAgICAgZmlsbCA9IE5BLCBkYXRhID0gZ3VzYSwgY29sb3IgPSAibGlnaHRncmV5IikgKwogICAgICBjb29yZF9tYXAoImJvbm5lIiwgcGFyYW1ldGVycyA9IDQxLjYpICsgZ2d0aGVtZXM6OnRoZW1lX21hcCgpKwogICAgICBzY2FsZV9maWxsX2dyYWRpZW50MigpCiAgICAgICAjIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIndoaXRlIiwgaGlnaCA9ICJyZWQiLCBuYS52YWx1ZSA9ICJncmV5IikKICAgICAgIyBzY2FsZV9maWxsX2dyYWRpZW50bihjb2xvdXJzID0gdGVycmFpbi5jb2xvcnMoMTApKQogIH0KCiAgaWYgKHBlcmNlbnRpbGUgPT0gVFJVRSl7CiAgICBwbHQgPC0gZ2dwbG90KGdjb3VudHlfcG9wKSArCiAgICAgIGdlb21fcG9seWdvbihhZXMobG9uZywgbGF0LCBncm91cCA9IGdyb3VwLCBmaWxsID0gcGNscyksCiAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJncmV5Iiwgc2l6ZSA9IDAuMSkgKwogICAgICBnZW9tX3BvbHlnb24oYWVzKGxvbmcsIGxhdCwgZ3JvdXAgPSBncm91cCksCiAgICAgICAgICAgICAgICAgICBmaWxsID0gTkEsIGRhdGEgPSBndXNhLCBjb2xvciA9ICJsaWdodGdyZXkiKSArCiAgICAgIGNvb3JkX21hcCgiYm9ubmUiLCBwYXJhbWV0ZXJzID0gNDEuNikgKyBnZ3RoZW1lczo6dGhlbWVfbWFwKCkgKwogICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBteWNvbG9ycywgbmEudmFsdWUgPSAiZ3JleSIpICsKICAgICAgIyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gInZpcmlkaXMiLCBuYS52YWx1ZSA9ICJncmV5IikgKwogICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJIZWx2ZXRpY2EiLCBmYWNlID0gImJvbGQiLCBzaXplID0gKDE1KSksCiAgICAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSksIAogICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibGVmdCIpCiAgfQogIHBsdCA8LSBwbHQgKyBsYWJzKGZpbGw9bGVnZW5kX3RpdGxlKSArIGdndGl0bGUoZ3JhcGhpY190aXRsZSkKICBwbHQKfQpgYGAKCmBgYHtyfQpzdWJzZXRfY2Vuc3VzCmBgYAoKYGBge3J9CnN1YnNldF9jZW5zdXNbJ3BjdF9pbmZlY3RlZCddIDwtIHN1YnNldF9jZW5zdXNbJ2NvbmZpcm1lZF9jYXNlcyddL3N1YnNldF9jZW5zdXNbJ3RvdGFsX3BvcCddCnN1YnNldF9jZW5zdXNbJ3BjdF9kZWF0aHMnXSA8LSBzdWJzZXRfY2Vuc3VzWydkZWF0aHMnXS9zdWJzZXRfY2Vuc3VzWyd0b3RhbF9wb3AnXQpzdWJzZXRfY2Vuc3VzJGNvdW50eV9maXBzX2NvZGUgPC1hcy5pbnRlZ2VyKHN1YnNldF9jZW5zdXMkY291bnR5X2ZpcHNfY29kZSkKc3Vic2V0X2NlbnN1cwpgYGAKYGBge3J9CnBsb3RfdnNfY291bnR5KHN1YnNldF9jZW5zdXMsICJwY3RfaW5mZWN0ZWQiLCBsZWdlbmRfdGl0bGUgPSAiUGVyY2VudCBJbmZlY3RlZCIpCnBsb3RfdnNfY291bnR5KHN1YnNldF9jZW5zdXMsICJwY3RfaW5mZWN0ZWQiLCBwZXJjZW50aWxlID0gVFJVRSwgYmFua3M9MTEsIAogICAgICAgICAgICAgICBsZWdlbmRfdGl0bGUgPSAiUGVyY2VudGlsZSBJbmZlY3RlZCIsCiAgICAgICAgICAgICAgIGdyYXBoaWNfdGl0bGUgPSAiUGVyY2VudGlsZSBvZiBQZXJjZW50YWdlIG9mIFBlb3BsZSBJbmZlY3RlZCBieSBDb3VudHkiKQpwbG90X3ZzX2NvdW50eShzdWJzZXRfY2Vuc3VzLCAicGN0X2RlYXRocyIsIHBlcmNlbnRpbGUgPSBUUlVFLCBiYW5rcz0xMSwgCiAgICAgICAgICAgICAgIGxlZ2VuZF90aXRsZSA9ICJQZXJjZW50aWxlIERlYXRocyIsCiAgICAgICAgICAgICAgIGdyYXBoaWNfdGl0bGUgPSAiUGVyY2VudGlsZSBvZiBQZXJjZW50YWdlIG9mIERlYXRocyBieSBDb3VudHkiKQpgYGAKCmBgYHtyfQpjZW5zdXNfY29ycl9jb2xzIDwtIGMoImRlYXRocyIsICJjb25maXJtZWRfY2FzZXMiLCAibWVkaWFuX2luY29tZSIsICJtYWxlX3BvcCIsCiAgICAgICAgICAgICAgICAgICAgICAiZmVtYWxlX3BvcCIsICJ0b3RhbF9wb3AiLCAibWVkaWFuX2FnZSIsICJ3b3JrZWRfYXRfaG9tZSIpCmdnY29ycihzdWJzZXRfY2Vuc3VzW2NlbnN1c19jb3JyX2NvbHNdLCBsb3c9InJlZCIsIG1pZD0iZ3JleSIsIGhpZ2g9ImJsdWUiLCBoanVzdD0gLjc1LCBzaXplPTMsIAogICAgICAgbGFiZWwgPSBUUlVFLCBsYWJlbF9zaXplID0gMywgbGFiZWxfY29sb3IgPSAid2hpdGUiKSArIGdncGxvdDI6OmxhYnModGl0bGUgPSAiUGVhcnNvbiBDb3JyZWxhdGlvbiBvZiBJbXBvcnRhbnQgVmFyaWFibGVzIikKYGBgCgoKYGBge3J9CmNvdW50cnlfZGF0ZV9wY3RfY2hhbmdlIDwtIGdsb2JhbF9tb2JpbGl0eV9yZXBvcnQgJT4lIHNlbGVjdChjb3VudHJ5X3JlZ2lvbl9jb2RlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGNvbnRhaW5zKCJkYXRlIikgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGNvbnRhaW5zKCJwZXJjZW50IikpCmNvdW50cnlfZGF0ZV9wY3RfY2hhbmdlCmBgYApgYGB7cn0KIyBjb3VudHJ5X2RhdGVfcGN0X2NoYW5nZSRyZXRhaWxfYW5kX3JlY3JlYXRpb25fcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZQp0ZXN0IDwtIGNvdW50cnlfZGF0ZV9wY3RfY2hhbmdlICU+JSBmaWx0ZXIoY291bnRyeV9yZWdpb25fY29kZSA9PSAiQUUiKSAlPiUgc2VsZWN0KGRhdGUgfCByZXRhaWxfYW5kX3JlY3JlYXRpb25fcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSkKZ2dwbG90KCBkYXRhID0gdGVzdCwgYWVzKCBkYXRlLCByZXRhaWxfYW5kX3JlY3JlYXRpb25fcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSApKSArIAogICMgZ2VvbV9saW5lKGFlcyh5PXJvbGxtZWFuKHJldGFpbF9hbmRfcmVjcmVhdGlvbl9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCBrPTIsIG5hLnBhZD1UUlVFKSkpCiAgZ2VvbV9saW5lKCkKYGBgCgpgYGB7cn0KCmxlbmd0aCh1bmlxdWUoY291bnRyeV9kYXRlX3BjdF9jaGFuZ2UkY291bnRyeV9yZWdpb25fY29kZSkpCiMgdW5pcXVlTihjb3VudHJ5X2RhdGVfcGN0X2NoYW5nZSwgYnkgPSBjKCJjb3VudHJ5X3JlZ2lvbl9jb2RlIikpCmBgYAoKYGBge3J9CnggPC0gCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCgo=